package com.acme.bankapp.domain.email.impl;

import java.awt.Window.Type;
import java.util.LinkedList;
import java.util.List;

import com.acme.bankapp.domain.email.Queue;
import com.acme.bankapp.domain.exceptions.EmptyEmailBoxException;
import com.acme.bankapp.domain.exceptions.MailCantBeAdded;

public class QueueImpl <Type> implements Queue <Type> {

	private List<Type> blckQueue = new LinkedList<Type>();
	private Object monitor = new Object();
	private final int maxMailBoxSize;
	private boolean isClosed = false;

	public QueueImpl(int mailBoxSize) {
		maxMailBoxSize = mailBoxSize;
	}

	public void addItem(Type item) throws MailCantBeAdded {

		synchronized (monitor) {			
			while (blckQueue.size() == maxMailBoxSize) {
				try {					
					monitor.wait();
					if (isClosed) {
						throw new InterruptedException();
					}
				} catch (InterruptedException e) {
					if (blckQueue.size() == maxMailBoxSize)
						throw new MailCantBeAdded();
					else
						break;
				}
			}			
			blckQueue.add(item);
			monitor.notify();			
		}
	}

	public Type getItem() throws EmptyEmailBoxException {
		synchronized (monitor) {			
			while (blckQueue.isEmpty()) {
				try {
					monitor.wait();
					if (isClosed) {
						throw new InterruptedException();
					}
				} catch (InterruptedException e) {
					if (blckQueue.isEmpty())
						throw new EmptyEmailBoxException();
					else
						break;
				}
			}		
			monitor.notify();			
			return blckQueue.remove(0);
		}
	}

	public void close() {
		synchronized (monitor) {
			isClosed = true;
			monitor.notify();
		}
	}
	
	public boolean isClosed () {
		return isClosed;
	}

}
